﻿#include "Reporting.h"

using namespace log4net;
using namespace Server::MirDatabase;

namespace Server::MirObjects
{

ILog *const Reporting::log = Logger::GetLogger(LogType::Player);

    Server::MessageQueue *Reporting::getMessageQueue()
    {
        return MessageQueue::getInstance();
    }

    Reporting::Reporting(PlayerObject *player) : _player(player)
    {
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void MapChange(MapInfo oldMap, MapInfo newMap, [CallerMemberName] string source = "")
    void Reporting::MapChange(MapInfo *oldMap, MapInfo *newMap, const std::string &source)
    {
        std::string message = StringHelper::formatSimple("Moved Map {0} => {1}", oldMap->FileName, newMap->FileName);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void ItemSplit(UserItem item, UserItem newItem, MirGridType grid, [CallerMemberName] string source = "")
    void Reporting::ItemSplit(UserItem *item, UserItem *newItem, MirGridType grid, const std::string &source)
    {
        std::string message = std::string::Format("Item Split - {0} from x{1} to x{2} in {3} - Created new item ({4}) x {5}", item->Info->Name, item->Count + newItem->Count, item->Count, grid, newItem->UniqueID, newItem->Count);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void ItemMerged(UserItem fromItem, UserItem toItem, int slotFrom, int slotTo, MirGridType gridFrom, MirGridType gridTo, [CallerMemberName] string source = "")
    void Reporting::ItemMerged(UserItem *fromItem, UserItem *toItem, int slotFrom, int slotTo, MirGridType gridFrom, MirGridType gridTo, const std::string &source)
    {
        std::string message = std::string::Format("Item Merged - {0} with {1} from {2} ({3}) to {4} ({5}) ({6})", fromItem->Info->Name, toItem->Info->Name, slotFrom, gridFrom, slotTo, gridTo, toItem->UniqueID);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void ItemCombined(UserItem fromItem, UserItem toItem, int slotFrom, int slotTo, MirGridType grid, [CallerMemberName] string source = "")
    void Reporting::ItemCombined(UserItem *fromItem, UserItem *toItem, int slotFrom, int slotTo, MirGridType grid, const std::string &source)
    {
        std::string message = std::string::Format("Item Combined - {0} with {1} from {2} to {3} in {4} ({5})", fromItem->Info->Name, toItem->Info->Name, slotFrom, slotTo, grid, toItem->UniqueID);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void ItemMoved(UserItem item, MirGridType from, MirGridType to, int slotFrom, int slotTo, string info = "", [CallerMemberName] string source = "")
    void Reporting::ItemMoved(UserItem *item, MirGridType from, MirGridType to, int slotFrom, int slotTo, const std::string &info, const std::string &source)
    {
        std::string message = std::string::Format("Item Moved - {0} from {1}:{2} to {3}:{4} ({5}) {6}", (item != nullptr ? item->Info->Name : "Empty"), from, slotFrom, to, slotTo, item == nullptr ? std::any() : item->UniqueID, info);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void ItemChanged(UserItem item, uint amount, int state, [CallerMemberName] string source = "")
    void Reporting::ItemChanged(UserItem *item, unsigned int amount, int state, const std::string &source)
    {
        std::string type = "";

        switch (state)
        {
            case 1:
                type = "Lost";
                break;
            case 2:
                type = "Gained";
                break;
        }

        std::string message = std::string::Format("Item {0} - {1} x{2} ({3})", type, item->Info->Name, amount, item->UniqueID);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void ItemGSBought(GameShopItem item, uint amount, uint CreditCost, uint GoldCost, [CallerMemberName] string source = "")
    void Reporting::ItemGSBought(GameShopItem *item, unsigned int amount, unsigned int CreditCost, unsigned int GoldCost, const std::string &source)
    {
        std::string message = std::string::Format("Purchased {0} x{1} for {2} Credits and {3} Gold.", item->Info->getFriendlyName(), amount, CreditCost, GoldCost);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void ItemMailed(UserItem item, uint amount, int reason, [CallerMemberName] string source = "")
    void Reporting::ItemMailed(UserItem *item, unsigned int amount, int reason, const std::string &source)
    {
        std::string msg;
        switch (reason)
        {
            case 1:
                msg = "Could not return item to bag after trade.";
                break;
            case 2:
                msg = "Item rental expired.";
                break;
            case 3:
                msg = "Could not return item to bag after rental.";
                break;
            default:
                msg = "No reason provided.";
                break;
        }

        std::string message = StringHelper::formatSimple("Mailed {0} x{1}. Reason : {2}.", item->Info->getFriendlyName(), amount, msg);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void GoldChanged(uint amount, bool lost = true, string info = "", [CallerMemberName] string source = "")
    void Reporting::GoldChanged(unsigned int amount, bool lost, const std::string &info, const std::string &source)
    {
        std::string message = StringHelper::formatSimple("Gold{0} - x{1} {2}", (lost ? "Lost" : "Gained"), amount, info);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void CreditChanged(uint amount, bool lost = true, string info = "", [CallerMemberName] string source = "")
    void Reporting::CreditChanged(unsigned int amount, bool lost, const std::string &info, const std::string &source)
    {
        std::string message = StringHelper::formatSimple("Credit{0} - x{1} {2}", (lost ? "Lost" : "Gained"), amount, info);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void ItemError(MirGridType from, MirGridType to, int slotFrom, int slotTo, [CallerMemberName] string source = "")
    void Reporting::ItemError(MirGridType from, MirGridType to, int slotFrom, int slotTo, const std::string &source)
    {
        std::string message = std::string::Format("Item Moved Error - from {0}:{1} to {2}:{3}", from, slotFrom, to, slotTo);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void KilledPlayer(PlayerObject obj, string info = "", [CallerMemberName] string source = "")
    void Reporting::KilledPlayer(PlayerObject *obj, const std::string &info, const std::string &source)
    {
        std::string message = StringHelper::formatSimple("Killed Player {0} {1}", obj->getName(), info);

        LogMessage(message, source);
    }

//C# TO C++ CONVERTER NOTE: The following .NET attribute has no direct equivalent in C++:
//ORIGINAL LINE: public void KilledMonster(MonsterObject obj, string info = "", [CallerMemberName] string source = "")
    void Reporting::KilledMonster(MonsterObject *obj, const std::string &info, const std::string &source)
    {
        std::string message = StringHelper::formatSimple("Killed Monster {0} {1}", obj->getName(), info);

        LogMessage(message, source);
    }

    void Reporting::Levelled(int level)
    {
        std::string message = StringHelper::formatSimple("Levelled to {0}", level);

        LogMessage(message, "");
    }

    void Reporting::Died(const std::string &map)
    {
        std::string message = StringHelper::formatSimple("Died - Map {0}", map);

        LogMessage(message, "");
    }

    void Reporting::Connected(const std::string &ipAddress)
    {
        std::string message = StringHelper::formatSimple("Connected - {0}", ipAddress);

        LogMessage(message, "");
    }

    void Reporting::Disconnected(const std::string &reason)
    {
        std::string message = StringHelper::formatSimple("Disconnected - {0}", reason);

        LogMessage(message, "");
    }

    void Reporting::LogMessage(const std::string &message, const std::string &source)
    {
        try
        {
            auto logMessage = StringHelper::formatSimple("{0} - {1} : {2}", _player->getName(), source, message);

            log->Info(logMessage);
        }
        catch (const std::runtime_error &ex)
        {
            getMessageQueue()->Enqueue(ex);
        }
    }
}
